﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;

namespace Fa.Util
{
	internal static class UnhandledExceptionHandler
	{
		internal static void StartCapture()
		{
			AppDomain.CurrentDomain.UnhandledException += Handler;
		}

		[DllImport("dbghelp.dll",
		  EntryPoint = "MiniDumpWriteDump",
		  CallingConvention = CallingConvention.StdCall,
		  CharSet = CharSet.Unicode,
		  ExactSpelling = true, SetLastError = true)]
		private extern static bool mdmpwrite(IntPtr hprocess, uint pid, IntPtr hfile, uint dump_type, IntPtr exparam, IntPtr user_stream_param, IntPtr callback_param);

		[DllImport("kernel32.dll", EntryPoint = "GetCurrentProcess", ExactSpelling = true)]
		private extern static IntPtr gethprocess();

		[DllImport("kernel32.dll", EntryPoint = "GetCurrentProcessId", ExactSpelling = true)]
		private extern static uint getpid();

		private static void Handler(object sender, UnhandledExceptionEventArgs eargs)
		{
#if DEBUG
			using (FileStream mdmp = File.OpenWrite(".\\jhplayer.mdmp"))
			{
				IntPtr hprocess = gethprocess();
				uint pid = getpid();
				IntPtr hfile = mdmp.SafeFileHandle.DangerousGetHandle();
				mdmpwrite(hprocess, pid, hfile, 0u, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
			}
			using (FileStream exobj = File.OpenWrite(".\\exception"))
			{
				BinaryFormatter fmt = new BinaryFormatter();
				if(eargs.ExceptionObject is Exception)
					fmt.Serialize(exobj, eargs.ExceptionObject);
			}
#endif
		}
	}
}